package demo002;
/**
 * 
 * @author zanglaowei
 * 学习Java反射机制
 */

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class demo002 {
	public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
		
//		TestUser();
//		System.out.println("-----------------------------------------------------------");
		
		TestgetDeclareMethods();
		System.out.println("------------------------------------------------------");
		
		
		User user = new User();
		Class<? extends User> clazz = user.getClass();
		//invoke 调用 方法
		Method tepMethodA=clazz.getMethod("publicUserMethod");
		tepMethodA.invoke(user);
		Method tepMethodB=clazz.getDeclaredMethod("privateUserMethod");
		//会报错
		//if (tepMethodB!=null) tepMethodB.invoke(clazz.newInstance());
		
		System.out.println("------------------------------------------");
	    //使用newInstance创建Class的示例，默认会使用无参构造器，并且无参构造器不能私有
		User newInstance2 = (User) clazz.newInstance();
		newInstance2.publictest();
		System.out.println("------------------------------------------");	
		//使用指定构造器创建Class示例
		Constructor<?> constructor = clazz.getConstructor(String.class,int.class);
		Object[] obj = new Object[]{"张大炮",28};
		User newInstance = (User)constructor.newInstance(obj);
		newInstance.publictest();
		
		
		System.out.println("------------------------------------------");
		getClass(User.class).publictest();
		
	}
	
	
	public static <T> T getClass(Class<T> clazz){

		//使用构造器
		
		try {
			
			Constructor tempConstructor;
			tempConstructor = clazz.getDeclaredConstructor();
			return (T) tempConstructor.newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;

//		
	}
	/**
	 * 此 Class 对象所表示的类或接口（包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口）的公共 member 方法,包含继承的
	 */
	public static void TestUser(){
		Method[] methods =User.class.getMethods();
		
		for (Method m : methods) {
			//getParameterTypes：方法参数类型数组
			System.out.println("方法参数类型数组长度："+m.getParameterTypes().length);
			System.out.println("方法名字："+m.getName());
		}
	}
	/**
	 * 此 Class 对象表示的类或接口声明的所有方法，包括公共、保护、默认（包）访问和私有方法，但不包括继承的方法
	 */
	public static void TestgetDeclareMethods(){
		 
		Class<? extends User> clazz = User.class;

		//getDeclaredMethods()
		System.out.println("↓↓↓↓↓↓↓↓↓↓↓↓getDeclaredMethods()↓↓↓↓↓↓↓↓↓↓↓");
		Method[] declaredMethods = clazz.getDeclaredMethods();
		
		for (Method method : declaredMethods) {
			System.out.println("方法参数数组长度："+ method.getParameterTypes().length);
			System.out.println("方法名："+method.getName());
		}
	}
	
	public static void TestgetMethod(){
		User user = new User();
		 
		Class<? extends User> clazz = user.getClass();
		//getMethods
		System.out.println("↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓getMethods()↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓");
		Method[] methods = clazz.getMethods();
		
		for (Method method : methods) {
			System.out.println("方法："+ method.getParameterTypes());
			System.out.println(method.getName());
		}
	}
       
}
